import { Checkbox, Space, message, Button, Alert } from 'antd';
import {
    ModalForm,
    ProFormSelect
} from '@ant-design/pro-form';
import React, { useEffect, useRef, useState } from 'react';

import type { ActionType } from '@ant-design/pro-table';
import {
    getApiPermissionOptions as GetPermissionOptions
} from '@/services/furion-cms/permission';
import type { ModalProps } from 'antd';
import type { ProFormInstance } from '@ant-design/pro-form';
import ProTable from '@ant-design/pro-table';
import { useIntl } from 'umi';
import { CloseOutlined } from '@ant-design/icons';
import ProDescriptions from '@ant-design/pro-descriptions';
import { putApiUserByIdPermissions as UpdatePermissions } from '@/services/furion-cms/user';
import styles from '../index.less';

interface PersonPermissionProps {
    modalVisible?: boolean;
    recored?: Partial<API.UserDto & { permissions: string[] }>;
    onVisibleChange: (visit: boolean) => void;
    modalProps?: Omit<ModalProps, 'visible'>;
}

const PersonPermission: React.FC<PersonPermissionProps> = (props) => {
    const { modalVisible, onVisibleChange, modalProps, recored } = props;
    /**
         * @en-US International configuration
         * @zh-CN 国际化配置
         * */
    const intl = useIntl();

    const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
    const [expandedRowKeys, setExpandedRowKeys] = useState<string[]>([]);
    const [operateDepends, setOperateDepends] = useState<string[]>([]);
    const [checkStrictly, setCheckStrictly] = useState<boolean>(true);
    // 数据源
    const [permissionData, setPermissionData] = useState<API.PermissionOptionsDto[]>();
    const [loading, setLoading] = useState<boolean>(true);

    const [configureItems, updateConfigureItems] = useState<string[]>([]);

    // 当操作依赖变化时进行与selectedRowKeys合并
    useEffect(() => {
        setSelectedRowKeys(Array.from(new Set([...selectedRowKeys, ...operateDepends])));
    }, [operateDepends]);

    const actionRef = useRef<ActionType>();
    // 绑定一个 ProFormInstance 实例
    const formRef = useRef<ProFormInstance>();

    const finishHandle = () => {
        console.log('finishHandle-data', configureItems);
        return UpdatePermissions({ id: recored!.id! }, configureItems)
            .then(() => {
                message.success('用户权限配置保存成功')
                return true;
            });
    }

    const handlerFormPermission = (values: any[]) => {
        return Array.from(new Set(values.flat()));
    }
    /**
       * 递归获取权限操作列表
       * @param children 子数据集合
       * @param key 填充key前缀
       * @param isEmpty 是否清空
       * @returns 
       */
    const getPermissionOperateList = (children?: API.PermissionOptionsDto[], key?: string, isEmpty?: boolean) => {
        let resultValues: any;
        children?.forEach(f => {
            if (key) {
                resultValues = {
                    ...resultValues ?? {},
                    [`${key}${f.code}`]: isEmpty ? [] : f.operateList?.map(o => o.code),
                    ...getPermissionOperateList(f.children, key, isEmpty) ?? {}
                }
            }
            else {
                resultValues = [
                    ...resultValues ?? [],
                    ...f.operateList ?? [],
                    ...getPermissionOperateList(f.children, key, isEmpty) ?? []
                ]
            }
        });
        return resultValues;
    }

    const handlerConfigureItemUpdate = () => {
        // 先保存之前的数据
        const formValues = formRef.current?.getFieldFormatValue?.();
        let formResults: string[] = [];
        for (const k in formValues) {
            if (k.includes(`multiple_`)) {
                formResults = [...formResults, ...handlerFormPermission(formValues[k])];
            }
        }
        const currentSelected: string[] = selectedRowKeys;

        updateConfigureItems(Array.from(new Set([
            ...formResults,
            ...currentSelected
        ])))
    }

    const handlerPermissionData = (data: API.PermissionOptionsDto[], selectedValues: string[]) => {
        // 找到当前展开的行
        const expandedKeys = data.reduce((pre: string[], cur) => {
            // 递归处理
            const recursionHandler = (entity: API.PermissionOptionsDto, parentCode?: string[]) => {
                if (entity.children?.some(x => selectedValues.includes(x.code!))) {
                    pre.push(entity.code!);
                    parentCode?.forEach(p => pre.push(p));
                }
                entity.children?.forEach(f => {
                    recursionHandler(f, [...parentCode ?? [], entity.code!]);
                });
            }
            recursionHandler(cur);

            return Array.from(new Set(pre));

        }, []) ?? [];

        /**
         * 找到选中的行
         * 当前菜单层级最多支持3级,多于3级将不再做处理
         */
        const selectedKeys = data.reduce((pre: string[], cur) => {
            // 递归处理
            const recursionHandler = (entity: API.PermissionOptionsDto) => {
                const items = entity.children?.filter(t => selectedValues.includes(t.code!));
                items?.forEach(f => pre.push(f.code!));
                entity.children?.forEach(f => {
                    recursionHandler(f);
                })
            };
            recursionHandler(cur);

            return Array.from(new Set(pre));
        }, []) ?? [];

        setExpandedRowKeys(expandedKeys);
        setSelectedRowKeys(selectedKeys);
        console.log('handlerPermissionData-result', expandedKeys, selectedKeys)
    }

    const getPermissionModuleList = (data?: API.PermissionOptionsDto[]) => {
        let resultValues: string[] = [];
        data?.forEach(f => {
            resultValues = [...resultValues, f.code!, ...getPermissionModuleList(f.children)]
        })
        return resultValues;
    }

    const handlerSelectedAll = (data?: API.PermissionOptionsDto[]) => {
        // 获取并设置权限操作列表
        const setValues = getPermissionOperateList(data, `multiple_`);
        formRef.current?.setFieldsValue(setValues);
        // 获取并设置表格行选中行
        const rowSelectedList = getPermissionModuleList(data);
        setSelectedRowKeys(Array.from(new Set([...rowSelectedList, ...selectedRowKeys])))

        console.log('handlerSelectedAll', data, setValues);
        handlerConfigureItemUpdate();
    }

    const handlerClearSelected = (data?: API.PermissionOptionsDto[]) => {
        const setValues = getPermissionOperateList(data, `multiple_`, true);

        formRef.current?.setFieldsValue(setValues);
        // 获取并设置表格行选中行
        const rowSelectedList = getPermissionModuleList(data);

        setSelectedRowKeys(selectedRowKeys.filter(t => !rowSelectedList.includes(t)))
        console.log('handlerClearSelected', data, setValues);
        handlerConfigureItemUpdate();
    }

    const handlerSelectedTableAll = (e: any) => {
        const { checked } = e.target;
        const datas = permissionData?.flatMap(m => m.children!);
        const setValues = getPermissionOperateList(datas, "multiple_", !checked);
        formRef.current?.setFieldsValue(setValues);

        // 获取并设置表格行选中行
        const rowSelectedList = getPermissionModuleList(datas);

        setSelectedRowKeys(checked ? Array.from(new Set([...rowSelectedList, ...selectedRowKeys])) : [])

        console.log('handlerSelectedTableAll', checked, setValues);
        handlerConfigureItemUpdate();
    }

    // 数据加载
    useEffect(() => {
        if (modalVisible && recored) {
            setLoading(true);
            (async () => {
                try {
                    const { data } = await GetPermissionOptions();

                    // 先设置数据
                    updateConfigureItems([]);
                    setPermissionData(data);
                    handlerPermissionData(data!, recored?.permissions ?? []);
                } catch { }
            })();
            setLoading(false);
            setCheckStrictly(false);
        }

    }, [modalVisible, recored]);// eslint-disable-line react-hooks/exhaustive-deps

    useEffect(() => handlerConfigureItemUpdate(), [selectedRowKeys, expandedRowKeys, permissionData]); // eslint-disable-line react-hooks/exhaustive-deps

    return (<ModalForm
        modalProps={{
            destroyOnClose: true,
            width: 800,
            maskClosable: false,
            ...modalProps
        }}
        visible={modalVisible}
        formRef={formRef}
        onFinish={finishHandle}
        onVisibleChange={onVisibleChange}
        onFieldsChange={() => handlerConfigureItemUpdate()}
    >
        <ProDescriptions<API.UserDto>
            dataSource={recored}
            title="权限分配"
            tooltip="配置用户的权限范围"
            extra={<Button type="text" icon={<CloseOutlined />} onClick={() => onVisibleChange(false)} />}
            columns={[
                {
                    title: intl.formatMessage({
                        id: 'pages.user.nickName',
                        defaultMessage: '昵称'
                    }),
                    dataIndex: 'nickName'
                },
                {
                    title: intl.formatMessage({
                        id: 'pages.user.email',
                        defaultMessage: '电子邮件'
                    }),
                    dataIndex: 'email',
                },
                {
                    title: intl.formatMessage({
                        id: 'pages.user.phoneNumber',
                        defaultMessage: '手机号'
                    }),
                    dataIndex: 'phoneNumber',
                },
            ]}
        />
        <Alert className={styles.tableTopAlert}
            message="会加载从角色和组织机构角色继承的权限项，点击保存会额外创建一个权限副本"
            type="warning"
            showIcon
            closable />
        <ProTable<API.PermissionOptionsDto>
            rowKey="code"
            toolBarRender={false}
            actionRef={actionRef}
            search={false}
            loading={loading}
            rowSelection={{
                checkStrictly: checkStrictly,
                selectedRowKeys: selectedRowKeys,
                onChange: (selectedKeys) => {
                    setSelectedRowKeys(selectedKeys as string[]);
                },
            }}
            scroll={{
                scrollToFirstRowOnChange: true,
                y: 330
            }}
            tableAlertRender={false}
            columns={[
                {
                    title: intl.formatMessage({
                        id: 'pages.role.configure.module.name',
                        defaultMessage: '名称'
                    }),
                    dataIndex: 'name',
                },
                {
                    title: (<>
                        {intl.formatMessage({
                            id: 'pages.role.configure.module.operate',
                            defaultMessage: '功能列表'
                        })}
                        <Checkbox key="selectedAll" style={{ float: 'right' }} onChange={handlerSelectedTableAll}>授予所有权限</Checkbox>
                    </>),
                    dataIndex: 'operateList',
                    width: 450,
                    render: (_: any, entity: API.PermissionOptionsDto) => {
                        const optionData: API.PermissionDto[] = entity.operateList ?? [];
                        if (optionData.length) {
                            const operateList = optionData.map(({ name, code }) => ({ label: name!, value: code! }));
                            const initialValue = optionData.filter(o => recored?.permissions?.includes(o.code!)).map(i => i.code);

                            return <ProFormSelect
                                name={`multiple_${entity.code}`}
                                options={[...operateList]}
                                initialValue={initialValue}
                                fieldProps={{
                                    mode: "multiple",
                                    allowClear: true,
                                    style: { width: '100%' },
                                    showArrow: true,
                                    maxTagCount: 'responsive' as const,
                                    onChange: (values) => {
                                        if (values.length) {
                                            setOperateDepends(Array.from(new Set([...operateDepends, entity.code!])));
                                        }
                                    },
                                    placeholder: '点击配置允许的使用的功能'
                                }}
                                noStyle={true}
                            />
                        }
                        else {
                            const childrenOptions = getPermissionOperateList(entity.children);
                            if (childrenOptions?.length) {
                                const formValues = formRef.current?.getFieldFormatValue?.();
                                const recursionOptions = (children?: API.PermissionOptionsDto[]) => {
                                    let values: string[] = [];
                                    children?.forEach(f => {
                                        values = [
                                            ...values,
                                            ...formValues?.[`multiple_${f.code}`] ?? [],
                                            ...recursionOptions(f.children) ?? []
                                        ]
                                    });
                                    return values;
                                }
                                const selectOptions = recursionOptions(entity.children);
                                // 当存在已选项才会显示
                                if (selectOptions?.length) {
                                    return <>
                                        <span style={{ color: '#909399' }}>已选择 {selectOptions?.length} 项 / 总共 {childrenOptions?.length} 项</span>
                                        <Space size={14} style={{
                                            float: 'right'
                                        }}>
                                            <a onClick={() => handlerSelectedAll(entity.children)}>全选</a>
                                            <a onClick={() => handlerClearSelected(entity.children)}>清除</a>
                                        </Space>
                                    </>
                                }
                            }
                            return;
                        }
                    }
                },
            ]}
            dataSource={permissionData}
            pagination={false}
            expandable={{
                expandedRowKeys: expandedRowKeys,
                onExpandedRowsChange: (expandedKeys) => {
                    setExpandedRowKeys(expandedKeys as string[])
                }
            }}
        />
    </ModalForm>)
}

export default PersonPermission;